<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2017/11/8
 * Time: 14:56
 * used to test transaction and phpunit
 */
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Controllers\Common as helper;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Laravel\Lumen\Routing\Controller as BaseController;

class BiaoController extends BaseController{
    protected $tender_id,$user_id;
    function __construct()
    {
        DB::connection()->enableQueryLog(); // 开启查询日志
    }
    /**
     * add a product post method
     * @param Request $request
     * remark: must param: name(length 16),account(money:0.000000000),period(int num),time_start(unixtime,not default now),time_end(unixtime,not default now),lowest_account(money),most_account(money)
     * remark: default param: status(default 1)
     */
    public function add(Request $request){
        // 不需要验证提交方式，因为路由前面已经限定了post了，也不需要一个一个判断是否存在对应值，只需要把值获取了以后，直接用validate去判断即可
        //$bad_words = "共产党,毛泽东,鸦片,白粉,AK47,枪";
        $this->validate($request,[
            'is_new_hand' => 'required|in:1,2',
            'type' => 'required|in:1,2',
            'contract_no' => 'required|exists:contract,contract_no|unique:borrow,contract_no', // 验证合同号在合同表中存在，并且在borrow表中未被使用
            'period' => 'required|digits:14|unique:borrow', // 竟然没有验证刚好14位的。。。regex:/\d{14}/
            'name' => 'required|max:8',
            'borrower_id' => 'required|numeric|exists:user,id',
            'account' => 'required|numeric',
            'style' => 'in:0',
            'apr' => 'required|numeric',
            'add_apr' => 'numeric',
            'add_apr_show' => 'required_with:add_apr',
            'lowest_account' => 'required|numeric',
            'most_account' => 'required|numeric|Bigger:lowest_account', // 自定义一个Bigger ^_^
            'time_start' => 'required|date-format:Y-m-d',
            'time_end' => 'required|date-format:Y-m-d|after_or_equal:time_start',
            'order_commend' => 'integer',
            'time_limit' => 'required|integer',
            'cycle_unit' => 'required|in:1,3'
        ]);
        $post = $request->all();
        helper::dump($post);
        $res = DB::table('borrow')->insert($post);
        $result = array('code'=>'100','msg'=>'success');
        if(!$res){
            $result = array('code'=>'-100','msg'=>'error');
        }
        echo json_encode($result);
    }

    // 不能直接这样写sql语句，会被注入。
    public function safe(Request $request){
        $post = $request->all();
//        helper::dump($post);
        $sql = sprintf(
            'UPDATE hj_user SET password = %s WHERE id = %s',
            $post['password'],
            $post['id']
        );
        echo $sql;
//        DB::table('user')->where('id',$post['id'])->update(['password'=>$post['password']]);
//        echo helper::last_query();
    }

    // lumen 事务
    public function active(Request $request){
        $res = array('code'=>'100','msg'=>'success');
        // 验证参数，标的id是否存在，标的状态是否正确
        $this->validate($request,[
            'borrow_id' => 'required|integer|exists:borrow,id',
            'status' => 'required|in:2|',
        ]);
        $borrow_id = $request->get('borrow_id');
        $status = $request->get('status');
        // 事务开始
        DB::beginTransaction();
        try{
        // 修改标的状态
        $borrow['status'] = $status;
        $bres = DB::table('borrow')->where('id',$borrow_id)->update($borrow);
        if(!$bres){
            throw new \Exception('update borrow failed');
        }
        // 修改everyday
        $eid = '1509984000';
        $every_day['total_borrow'] = 1000;
        $eres = DB::table('every_day')->where('date_time',$eid)->increment('total_borrow',$every_day['total_borrow']);//让字段自增给定值。
        if(!$eres){
            throw new \Exception('update every_day failed');
        }
        DB::commit();
        // 事务结束
        }catch (\Exception $e){
            DB::rollBack();
            $res = array('code'=>'-100','msg'=>$e->getMessage());
        }
        // 返回结果

        echo json_encode($res);

    }

    // 测试string
    public function string(Request $request){
        $str = $request->get('str');
        echo Str::ascii($str)."\n";
        echo Str::camel($str)."\n";
        var_dump(Str::contains($str,'33'))."\n";
        var_dump(Str::endsWith($str,'33'))."\n";
        var_dump(Str::finish($str,'33'))."\n";
        var_dump(Str::is($str,'33'))."\n";
        var_dump(Str::length($str))."\n";
        var_dump(Str::limit($str,6,'...'))."\n";
        var_dump(Str::words($str,2,'...'))."\n";
        var_dump(Str::lower($str))."\n";
        var_dump(Str::plural($str,2))."\n";
        var_dump(Str::random(32))."\n";
        var_dump(Str::quickRandom(32))."\n";
        var_dump(Str::upper($str))."\n";
        var_dump(Str::title($str))."\n";
        var_dump(Str::singular($str))."\n";
        echo Str::slug($str)."\n";
        echo Str::snake($str," ","_")."\n";
        echo Str::startsWith($str,"33")."\n";
        var_dump(Str::studly($str))."\n";
        var_dump(Str::macro($str,"33"))."\n";
    }

    // jsonp,查询出来所有>10000的标的
    public function json_p(Request $request){
        $result = array('code'=>'100','info'=>'success');
        $account = $request->get('account');
        $callback= $request->get('callback',true);
        $res = DB::table("borrow")->where('account','>=',$account)->join('user','user.id',"=",'borrow.borrower_id')->select('borrow.name','borrow.account','user.realname','borrow.create_time')->orderBy('borrow.account','desc')->get();
        if(!empty($res)){
            $result['info'] = $res;
        }else{
            $result = array('code'=>'-100','info'=>'no data');
        }
        $result = json_encode($result);
        echo $callback."($result)";
    }

    // 自定义的response方式
    public function json_p_response(Request $request){
        $result = array('code'=>'100','info'=>'success');
        $account = $request->get('account');
        $res = DB::table("borrow")->where('account','>=',$account)->join('user','user.id',"=",'borrow.borrower_id')->select('borrow.name','borrow.account','user.realname','borrow.create_time')->orderBy('borrow.account','desc')->get();
        if(!empty($res)){
            $result['info'] = $res;
        }else{
            $result = array('code'=>'-100','info'=>'no data');
        }
        return response()->json($result)->setCallback($request->get('callback'));
    }



    /**
     * 用来写回款表测试
     */
    public function make_collection(Request $request){
        $this->tender_id = intval($request->get('tender_id'));
        $this->user_id = intval($request->get('user_id'));
        // 从这里复制到脚本中
        // 获取投资信息
        $tender = DB::table('borrow_tender')->where('id', $this->tender_id)->first();
        if(!$tender){
            exit("投资数据错误");
        }
        // 获取标的信息
        $borrow = DB::table('borrow')->where('id',$tender->borrow_id)->first();
        if(!$borrow){
            exit("标的数据错误");
        }
        // 查询当前投资下是否生成了足够的回款信息
        $is_make = false;
        $collections = DB::table('borrow_collection')->where('tender_id',$this->tender_id)->count();
        if($collections == 0){// 尚未生成回款信息
            $is_make = true;
        }

        // 生成部分回款信息，需要下面先执行删除，然后再新增

        // 公式：   生成回款信息，用事务，如果失败，重新执行当前队列。
        if($borrow->style == 0){ // 一次性还本付息
            // 一次性还款每笔投资只生成一个回款信息
            if($collections == 1){
                exit("回款已生成");
            }
            // 如果一次性还款生成多笔回款信息，则生成错误，需要删掉重新生成
            if($collections > 1){
                // 删除原有的
                DB::table('borrow_collection')->where('tender_id',$this->tender_id)->delete();
                $is_make = true;
            }
            if($is_make){
                $res = $this->interest_once($borrow,$tender);
            }
        }else if($borrow->style == 1){ // 按月付息到期还本

            if($collections == $borrow->time_limit){// 回款信息等于借款月
                exit("回款已生成");
            }
            // 生成大于分期数量，或者生成了部分信息，都要删掉重新开始；
            if($collections > $borrow->time_limit || ($collections < $borrow->time_limit && $collections > 0)){
                // 删除原有的
                DB::table('borrow_collection')->where('tender_id',$this->tender_id)->delete();
                $is_make = true;
            }
            if($is_make){
                $res = $this->interest_month($borrow,$tender);
            }
        }
        // 执行入库操作
        if($res){
            foreach($borrow->results as $key => $value){
                $collection_data = [
                    'tender_id' => $this->tender_id,
                    'user_id' => $this->user_id,
                    'borrow_id' => $tender->borrow_id,
                    'trade_no' => helper::create_hf_no(),
                    'order_number' => $key,
                    'status' => 1,
                    'repay_account' => $value['repayment_account'],
                    'capital' => $value['capital'],
                    'interest' => $value['interest'],
                    'repay_time' => $value['repayment_time'],
                    'creater' => $this->user_id,
                    'create_time' => time(),
                    'updater' => $this->user_id,
                    'update_time' => time(),
                ];
                $coll_id = DB::table('borrow_collection')->insertGetId($collection_data);
                helper::write_log('make_collection_'.date('Y-m').".log",$coll_id."\n");
            }

        }
        echo "ok";
    }

    /**
     * 一次性还款
     *
     * @return boolean
     */
    private function interest_once(&$borrow,&$tender)
    {
        $borrow->results = array();

        if($borrow->style != 0)
        {
            return false;
        }

        if(empty($tender->money))
        {
            return false;
        }

        if(empty($borrow->apr))
        {
            return false;
        }

        if(empty($borrow->time_limit))
        {
            return false;
        }

        if(empty($borrow->time_start))
        {
            $this->time_start = time();
        }

        if($borrow -> cycle_unit == 1){
            // 日
            $interest = round($tender->money * $borrow->apr/365*$borrow->time_limit, 2);//利息等于应还金额乘季利率
        }elseif($borrow -> cycle_unit == 3){
            // 月
            $interest = round($tender->account * $borrow->apr/12*$borrow->time_limit, 2);//利息等于应还金额乘月利率
        }
        $capital = round($tender->money, 2);//本金利息都一样
        for($i = 1; $i <= 1; $i++)
        {
            $borrow->results[$i]['repayment_account'] = $interest + $capital;
            $borrow->results[$i]['repayment_time'] = $borrow->time_limit*86400 + $borrow->time_start;
            $borrow->results[$i]['interest'] = $interest;
            $borrow->results[$i]['capital'] = $capital;
        }
        return true;
    }

    /**
     * 到期还本，按月付息
     *
     * @return boolean
     */
    private function interest_month(&$borrow,&$tender)
    {
        $borrow->results = array();

        if($borrow->style != 1)
        {
            return false;
        }

        if(empty($tender->money))
        {
            return false;
        }

        if(empty($borrow->apr))
        {
            return false;
        }

        if(empty($borrow->time_limit))
        {
            return false;
        }

        if(empty($borrow->time_start))
        {
            $borrow->time_start = time();
        }

        //月利率
        $month_apr = round($borrow->apr/12,9);
        $interest = round($tender->money * $month_apr, 2);//利息等于应还金额乘月利率

        // 总利息 投资金额*收益率*出借期限/12
        $interest_total = $tender->money*$borrow->apr*$borrow->time_limit/12;

        $capital = 0;
        $interest_sum = 0;
        for($i = 1; $i <= $borrow->time_limit; $i++)
        {
            if ($i == $borrow->time_limit)
            {
                $interest = $interest_total - $interest_sum;// 最后一个月的利息，等于总利息-之前的所有利息
                $capital = round($tender->money, 2);//本金只在最后一个月还，本金等于借入金额
            }else{
                $interest_sum += $interest;
            }

            $borrow->results[$i]['repayment_account'] = $interest + $capital;
            $borrow->results[$i]['repayment_time'] = helper::time_month_creater($i, $borrow->time_start);
            $borrow->results[$i]['interest'] = $interest;
            $borrow->results[$i]['capital'] = $capital;
        }

        return true;
    }
}